/*
 * OpeningProcessorFactory.java   2008/11/17
 *
 * Copyright 2008 Web & Zen Multimedia, All rights reserved.
 * Use is subject to license terms.
 */
package it.wzm.lightweightlog.annotation;

import it.wzm.lightweightlog.Dumper;
import it.wzm.lightweightlog.DumperDecorator;
import it.wzm.lightweightlog.DumperException;

/**
 * This is a decorator for dumper, it's a layer on top of Dumper and it's the place where we can
 * put operation to be done before opening and closing of dumper. 
 * @author Leonardo Celati
 */
public class OpeningProcessorFactory extends DumperDecorator {
	
	/**
	 * As required by serialization
	 */
	private static final long serialVersionUID = -2442977098204961907L;
	/**
	 * Holder for keepaliveProc
	 */
	private boolean keepingalive;
	/**
	 * Holder for killProcess
	 */
	private boolean killing;

	/**
	 * The only constructor
	 * @param d a valid Dumper
	 */
	public OpeningProcessorFactory(Dumper d) {
		super(d);

		// get our annotation...and value from it
		OpeningProcessor op = d.getClass().getAnnotation(OpeningProcessor.class);
		this.keepingalive = op.keepingalive();
		this.killing = op.killing();
	}	
	
    /**
     * Opening of the Dumper
     * @throws DumperException if something went wrong
     */
	@Override
    public void open() throws DumperException  {
        try {
      		
            // just opening the dumper if it's not already open...
            if (!this.getDumper().isOpen() ) {
                this.getDumper().open();
            }  else {
                return;
            }
            
        } catch (DumperException de) {
            // if we get here something went wrong
            // depends on flag we close the Dumper
            if (this.hasKillOnFailure())
                this.setStatus(Status.FAILURE);
            // then re throw the error...
            throw new DumperException(de);
        }
    }	
	
	/**
	 * Closing the dumper
	 */
	@Override
	public void close() throws DumperException {
		try {
			// basic check...
			if (!this.getDumper().isOpen())
				throw new DumperException("Already closed ");
			
			// if processor is acrivated and keepalive on dumper is true
			// then we can close the dumper, otherwise we can exit
			if (keepingalive  && this.getDumper().isKeepAlive()) {
				return;
			} else {
				this.getDumper().close();
			}			

		} catch (Exception ex) {
            // if we get here something went wrong
            // depends on flag we close the Dumper
			// and set its status and re throw error...
            if (this.hasKillOnFailure())
                this.setStatus(Status.FAILURE);
            
            throw new DumperException(ex);
		}
	}
	
	
	/**
	 * Killing dumper
	 */
	@Override
	public void kill() {
		// check first if we have kill proc active then
		// set globale status then call method...
        if (this.killing)
        	this.setStatus(Status.KILLED);
        
        this.getDumper().kill();
	}
	
	/**
	 * Overriding super method
	 */
	@Override
	public String toString() {
		return "@OpenPreProcessor"  + " - " + this.getDumper().toString() ;
	}
	
}
